#include  "Typedef.h"
#include  "macros.h"

#include  "hal_uart.h"
#include  "Timer.h"
#include  "CC2500.h"

#include  "Phy_Frame.h"
#include  "UARTprotocol.h"
#include  "Wirelessprotocol.h"
#include  "WirelessComm.h"

#include  "GlobalMethod.h"
#include  "eSeal_Management.h"

#include  "string.h"
#include  "stdlib.h"
#include  "SysComm.h"

#define  UARTPROTOCOL_DOWN_ID                           (0x5A)
#define  UARTPROTOCOL_UP_ID                             (0xA5)

#define  UARTPROTOCOL_DATA_POS_PROTOCOLID               (0)
#define  UARTPROTOCOL_DATA_POS_READERID                 (UARTPROTOCOL_DATA_POS_PROTOCOLID + 1)
#define  UARTPROTOCOL_DATA_POS_LEN                      (UARTPROTOCOL_DATA_POS_READERID + FRAME_DATA_LTH_READERID)               
#define  UARTPROTOCOL_DATA_POS_DATA                     (UARTPROTOCOL_DATA_POS_LEN + 1)

#define  CMD_SET_READERID_OPTION_CHANNEL                (0x01)
#define  CMD_SET_READERID_OPTION_POWER                  (0x02)
#define  CMD_SET_READERID_OPTION_INOUT                  (0x03)


extern  INT8U  CurrentReaderID[];
extern  READER_PROPERTY  ReaderProperty;
extern  SYS_COMM_STATUS_WORD  SysCommStatus;
extern  FLASH  INT8U CC2500_RFPowerTable[];

UART_RX_FRAME  uart_rxBuf;

INT8U  UartProtocol_RecvPacket(UART_RX_FRAME* pUartRecvPacket);
INT8U  UartProtocol_SendPacket(INT8U* pData , INT8U Len);
UART_RX_FRAME*   UartProtocol_ParsePacket(UART_RX_FRAME* pUartRecvPacket);

INT8U  UartProtocol_RecvPacket(UART_RX_FRAME* pUartRecvPacket)
{
    INT8U  i , LrcTemp , err , ProtocolID;
    INT8U  ReadIDTemp[FRAME_DATA_LTH_READERID] = {0xff , 0xff};
    err = UARTPROTOCOL_DOWN_NO_ERR;

    ASSERT(pUartRecvPacket);

    if (usart_ischarinrxfifo())
    {
        ProtocolID = usart_getchar();
        if (ProtocolID == UARTPROTOCOL_DOWN_ID)
        {          
            for (i = 0 ; i < FRAME_DATA_LTH_READERID ; i++)
            {
                pUartRecvPacket->ReaderID[i] = usart_getchar();
            }
            if((memcmp(ReadIDTemp , pUartRecvPacket->ReaderID , FRAME_DATA_LTH_READERID) == 0)
             ||(memcmp(CurrentReaderID,pUartRecvPacket->ReaderID , FRAME_DATA_LTH_READERID) == 0))
            {
                pUartRecvPacket->Length = usart_getchar();

                for (i = 0 ; i < (pUartRecvPacket->Length) ; i++)
                {
                    pUartRecvPacket->Data[i] = usart_getchar();
                }
                
                LrcTemp = Lrc((INT8U*)(pUartRecvPacket) , UARTPROTOCOL_DOWN_DEFAULT_LENGTH + pUartRecvPacket->Length);
                if (LrcTemp == usart_getchar())
                    ;
                else
                    err =  UARTPROTOCOL_DOWN_ERR_LRC;
            }//if(memcmp(CurrentReaderID , pUartRecvPacket->ReaderID , FRAME_DATA_LTH_READERID) == 0)
            else
                err = UARTPROTOCOL_DOWN_ERR_READERID_MISMATCH;
        }//if (pUartRecvPacket->Protocol == UARTPROTOCOL_DOWN_ID)
        else
          err = UARTPROTOCOL_DOWN_ERR_PROTOCOLID_MISMATCH;
    }//if (usart_ischarinrxfifo())
    else
        err = UARTPROTOCOL_DOWN_ERR_NODATA;

    return err;
}



UART_RX_FRAME* UartProtocol_ParsePacket(UART_RX_FRAME* pUartRecvPacket)
{
    
    switch (pUartRecvPacket->Data[0])
    {    
    case UARTPROTOCOL_CMD_RD_ESEAL_ID:
        {
            SysCommStatus.IsWirelessCommSuccess = FALSE;
            SysCommStatus.CommStatus = SYS_COMM_START;
        }
        break;
    case UARTPROTOCOL_CMD_RD_ESEAL_EVENT:
        {
            SysCommStatus.IsWirelessCommSuccess = FALSE;
            SysCommStatus.CommStatus = SYS_COMM_START;
        }
        break;
    case UARTPROTOCOL_CMD_RD_ESEAL_EVENTNUM:
        {
            SysCommStatus.IsWirelessCommSuccess = FALSE;
            SysCommStatus.CommStatus = SYS_COMM_START;
        }
        break;
    case UARTPROTOCOL_CMD_SET_INOUT:
        SysCommStatus.IsWirelessCommSuccess = FALSE;
        SysCommStatus.CommStatus = SYS_COMM_START;
        break;
    case UARTPROTOCOL_CMD_RD_ESEAL_RTC:
        SysCommStatus.IsWirelessCommSuccess = FALSE;
        SysCommStatus.CommStatus = SYS_COMM_START;
        break;
    case UARTPROTOCOL_CMD_SET_READER:
        {
            INT8U TempData[3];
            TempData[0] = UARTPROTOCOL_CMD_SET_READER;
            
            switch (pUartRecvPacket->Data[1])
            {
            case CMD_SET_READERID_OPTION_CHANNEL:
                ReaderProperty.UHF_CommChannel = pUartRecvPacket->Data[2];
                CC2500_SetLogicalChannel(ReaderProperty.UHF_CommChannel);
                
                TempData[1] = CMD_SET_READERID_OPTION_CHANNEL;
                TempData[2] = UART_COMM_SUCCESS;
             
                break;
            case CMD_SET_READERID_OPTION_POWER:
                ReaderProperty.UHF_Power = pUartRecvPacket->Data[2];
                CC2500_SetTxPower(CC2500_RFPowerTable[ReaderProperty.UHF_Power]);
                
                TempData[1] = CMD_SET_READERID_OPTION_POWER;
                TempData[2] = UART_COMM_SUCCESS;

                break;
            case CMD_SET_READERID_OPTION_INOUT:
                ReaderProperty.InOut = pUartRecvPacket->Data[2];
                
                TempData[1] = CMD_SET_READERID_OPTION_INOUT;
                TempData[2] = UART_COMM_SUCCESS;

                break;
            default:
                break;
            }
            
            UartProtocol_SendPacket(TempData , 3);
        }
        break;
    case  UARTPROTOCOL_CMD_OPERAT_READER:
        {
            INT8U  TempData[2];

            WirelessCommReset();

            TempData[0] = UARTPROTOCOL_CMD_OPERAT_READER;
            TempData[1] = 0x01;

            UartProtocol_SendPacket(TempData , 2);
        }
        break;
    case  UARTPROTOCOL_CMD_OPERAT_OVER_READER:
        {
            SysCommStatus.IsWirelessCommSuccess = FALSE;
            SysCommStatus.CommStatus = SYS_COMM_START;
        }
        break;
    default:
        break;
    }   
    return  pUartRecvPacket;
}


INT8U  UartProtocol_AnswerPacket(UART_RX_FRAME* pUartRecvPacket)
{
    INT8U  err = TRUE;
    INT8U  *pTempData;
    INT8U  TempDataLth;

    switch (pUartRecvPacket->Data[0])
    {    
    case UARTPROTOCOL_CMD_RD_ESEAL_ID:
        if (SysCommStatus.CommStatus == SYS_COMM_WIRELESS_END)
        {
            TempDataLth = FRAME_DATA_LTH_ESEALID + FRAME_DATA_LTH_VENDORID + 1;
            pTempData = (INT8U*)malloc(TempDataLth);
            if (pTempData)
            {
                ESEAL_DETAIL* peSeal;

                *(pTempData + 0) = pUartRecvPacket->Data[0];               
                peSeal = eSeal_Get_eSealObj();
                if (peSeal)
                {
                    memcpy(pTempData + 1, peSeal->VendorID , FRAME_DATA_LTH_VENDORID);
                    memcpy(pTempData + 1 + FRAME_DATA_LTH_VENDORID , peSeal->eSealID , FRAME_DATA_LTH_ESEALID);
                    
                    UartProtocol_SendPacket(pTempData , 1 + FRAME_DATA_LTH_VENDORID + FRAME_DATA_LTH_ESEALID);
                }
                else
                {
                    err = FALSE;
                }
                free(pTempData);
            }
            else
            {
                err = FALSE;
            }
            
        }
        break;
    case UARTPROTOCOL_CMD_RD_ESEAL_EVENT:
        if (SysCommStatus.CommStatus == SYS_COMM_WIRELESS_END)
        {
            ESEAL_DETAIL* peSeal;
            ESEAL_DATA* pData;
            INT8U  EventNum;
            
            TempDataLth = FRAME_DATA_LTH_ESEALID + FRAME_DATA_LTH_VENDORID + 1 + 16;
            pTempData = (INT8U*)malloc(TempDataLth);
            EventNum = pUartRecvPacket->Data[1];
            if (pTempData)
            {
                peSeal = eSeal_Get_eSealObj();
                if (peSeal)
                {
                    *(pTempData + 0) = pUartRecvPacket->Data[0];
                    memcpy(pTempData + 1 , peSeal->VendorID , FRAME_DATA_LTH_VENDORID);
                    memcpy(pTempData + 1 + FRAME_DATA_LTH_VENDORID , peSeal->eSealID , FRAME_DATA_LTH_ESEALID);
                    
                    pData = eSealDataTable_Find_TypeData(peSeal , GET_ESEAL_DATA_TYPE(WIRELESSPROTOCOL_P2P_CMD_READ_EVENT_RECORD , EventNum));
                    if(pData)
                    {
                      memcpy(pTempData + 1 + FRAME_DATA_LTH_VENDORID + FRAME_DATA_LTH_ESEALID, pData->peSealData , pData->eSealDataLth);
                    
                      UartProtocol_SendPacket(pTempData , 1 + FRAME_DATA_LTH_ESEALID + FRAME_DATA_LTH_VENDORID + pData->eSealDataLth);
                    }
                }
                else
                {
                    err = FALSE;
                }
                free(pTempData);
            }
            else
            {
                err = FALSE;
            }
            
        }
        break;
    case UARTPROTOCOL_CMD_RD_ESEAL_EVENTNUM:
        if (SysCommStatus.CommStatus == SYS_COMM_WIRELESS_END)
        {
            ESEAL_DETAIL* peSeal;
            ESEAL_DATA* pData;
            TempDataLth = FRAME_DATA_LTH_ESEALID + FRAME_DATA_LTH_VENDORID + 1 + 2;
            pTempData = (INT8U*)malloc(TempDataLth);
            
            if (pTempData)
            {
                peSeal = eSeal_Get_eSealObj();
                if (peSeal)
                {
                    *(pTempData + 0 ) = pUartRecvPacket->Data[0];
                    memcpy(pTempData + 1 , peSeal->VendorID , FRAME_DATA_LTH_VENDORID);
                    memcpy(pTempData + 1 + FRAME_DATA_LTH_VENDORID , peSeal->eSealID , FRAME_DATA_LTH_ESEALID);
                    
                    pData = eSealDataTable_Find_TypeData(peSeal , GET_ESEAL_DATA_TYPE(WIRELESSPROTOCOL_P2P_CMD_READ_EVENT_NUM , 0));
                    if(pData)
                    {
                      memcpy(pTempData + 1 + FRAME_DATA_LTH_VENDORID + FRAME_DATA_LTH_ESEALID , pData->peSealData, pData->eSealDataLth);
                    
                      UartProtocol_SendPacket(pTempData , 1 + FRAME_DATA_LTH_VENDORID + FRAME_DATA_LTH_ESEALID + pData->eSealDataLth);
                    }
                }            
                else
                {
                    err  = FALSE;
                }
                free(pTempData);
            }
            else
            {
                err = FALSE;
            }          
        }
        break;
    case UARTPROTOCOL_CMD_RD_ESEAL_RTC:
        if (SysCommStatus.CommStatus == SYS_COMM_WIRELESS_END)
        {
            ESEAL_DETAIL* peSeal;
            ESEAL_DATA* pData;
            TempDataLth = FRAME_DATA_LTH_ESEALID + FRAME_DATA_LTH_VENDORID + 1 + 4;
            pTempData = (INT8U*)malloc(TempDataLth);
            
            if (pTempData)
            {
                peSeal = eSeal_Get_eSealObj();
                if (peSeal)
                {
                    *(pTempData + 0 ) = pUartRecvPacket->Data[0];
                    memcpy(pTempData + 1 , peSeal->VendorID , FRAME_DATA_LTH_VENDORID);
                    memcpy(pTempData + 1 + FRAME_DATA_LTH_VENDORID , peSeal->eSealID , FRAME_DATA_LTH_ESEALID);
                    
                    pData = eSealDataTable_Find_TypeData(peSeal , GET_ESEAL_DATA_TYPE(WIRELESSPROTOCOL_P2P_CMD_READ_RTC , 0));
                    if(pData)
                    {
                      memcpy(pTempData + 1 + FRAME_DATA_LTH_VENDORID + FRAME_DATA_LTH_ESEALID , pData->peSealData, pData->eSealDataLth);
                    
                      UartProtocol_SendPacket(pTempData , 1 + FRAME_DATA_LTH_VENDORID + FRAME_DATA_LTH_ESEALID + pData->eSealDataLth);
                    }
                }            
                else
                {
                    err  = FALSE;
                }
                free(pTempData);
            }
            else
            {
                err = FALSE;
            }          
        }
        break;
    case UARTPROTOCOL_CMD_SET_INOUT:
        if (SysCommStatus.CommStatus == SYS_COMM_WIRELESS_END)
        {
            ESEAL_DETAIL* peSeal;
            TempDataLth = FRAME_DATA_LTH_ESEALID + FRAME_DATA_LTH_VENDORID + 1 + 1;
            pTempData = (INT8U*)malloc(TempDataLth);
            if (pTempData)
            {
                peSeal = eSeal_Get_eSealObj();
                if (peSeal)
                {
                    *(pTempData + 0 ) = pUartRecvPacket->Data[0];
                    memcpy(pTempData + 1 , peSeal->VendorID , FRAME_DATA_LTH_VENDORID);
                    memcpy(pTempData + 1 + FRAME_DATA_LTH_VENDORID , peSeal->eSealID , FRAME_DATA_LTH_ESEALID);
                    
                    *(pTempData + 1 + FRAME_DATA_LTH_VENDORID + FRAME_DATA_LTH_ESEALID) = ReaderProperty.InOut;

                    UartProtocol_SendPacket(pTempData , 1 + FRAME_DATA_LTH_VENDORID + FRAME_DATA_LTH_ESEALID + 1);
                    
                    WirelessCommReset();
                    eSeal_Del_eSealObj(peSeal); 
                }            
                else
                {
                    err = FALSE;
                }
                free(pTempData);
            
            }
            else
            {
                err = FALSE;
            }
            
             
        }
        break;
    case UARTPROTOCOL_CMD_SET_READER:
        
        break;
    case UARTPROTOCOL_CMD_OPERAT_READER:
      {
            ESEAL_DETAIL* peSeal;

            WirelessCommReset();
            peSeal = eSeal_Get_eSealObj();
            eSeal_Del_eSealObj(peSeal);
      }
      break;
    case UARTPROTOCOL_CMD_OPERAT_OVER_READER:
        if (SysCommStatus.CommStatus == SYS_COMM_WIRELESS_END)
        {
            INT8U  TempData[2];
            ESEAL_DETAIL* peSeal;

            WirelessCommReset();
            peSeal = eSeal_Get_eSealObj();
            eSeal_Del_eSealObj(peSeal);

            TempData[0] = UARTPROTOCOL_CMD_OPERAT_OVER_READER;
            TempData[1] = 0x01;
            
            UartProtocol_SendPacket(TempData , 2);           
        }
        break;
    default:
        err = FALSE;
        break;
    }
    
    return  err;
}

INT8U  UartProtocol_SendPacket(INT8U* pData , INT8U Len)
{
    INT8U  *pTempBuf;
    INT8U  i , PacketLenght;
    
    ASSERT(pData);

    PacketLenght = Len + UARTPROTOCOL_DOWN_DEFAULT_LENGTH + 2 ;

    pTempBuf = malloc(PacketLenght);
    if (pTempBuf)
    {
        *(pTempBuf + UARTPROTOCOL_DATA_POS_PROTOCOLID) = UARTPROTOCOL_UP_ID;
        
        memcpy((pTempBuf + UARTPROTOCOL_DATA_POS_READERID) , CurrentReaderID , FRAME_DATA_LTH_READERID);
        
        *(pTempBuf + UARTPROTOCOL_DATA_POS_LEN) = Len;
        
        memcpy((pTempBuf + UARTPROTOCOL_DATA_POS_DATA) , pData , Len);
        *(pTempBuf + Len + UARTPROTOCOL_DOWN_DEFAULT_LENGTH + 1) = Lrc((pTempBuf + UARTPROTOCOL_DATA_POS_READERID) , Len + UARTPROTOCOL_DOWN_DEFAULT_LENGTH);
        
        for (i = 0 ; i < PacketLenght; i++)
        {
            usart_putchar(pTempBuf[i]);
        }
        
        free(pTempBuf);
        return  TRUE;
    }
    else
        return  FALSE;
    
}